package org.ofbiz.wvtools.webtools;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;

import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.UtilProperties;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.entity.GenericValue;
import org.ofbiz.service.DispatchContext;
import org.ofbiz.service.GenericServiceException;
import org.ofbiz.service.LocalDispatcher;
import org.ofbiz.service.ModelParam;
import org.ofbiz.service.ModelPermGroup;
import org.ofbiz.service.ModelPermission;
import org.ofbiz.service.ModelService;
import org.ofbiz.service.ModelServiceIface;
import org.ofbiz.service.ServiceUtil;
import org.ofbiz.service.calendar.RecurrenceRule;
import org.ofbiz.service.config.ServiceConfigUtil;
import org.ofbiz.webapp.event.CoreEvents;

public class WvToolsServiceManage {
	public static final String module = WvToolsServiceManage.class.getName();
    public static final String resource = "WvtoolsUiLabels";
	
    public static  Map<String,Object> listWvToolsService(DispatchContext ctx, Map<String, ? extends Object> context){
    	Map<String,Object> result = ServiceUtil.returnSuccess();
    	
        Set<String> serviceNames = ctx.getAllServiceNames();
        
        List servicesList = new ArrayList(serviceNames.size());
       
        Integer servicesFoundCount = 0;
        try {
        
        for (String serviceName : serviceNames) {  
      
            Map curServiceMap = new HashMap();
            curServiceMap.put("serviceName", serviceName);
            ModelService curServiceModel = ctx.getModelService(serviceName);

            if (curServiceModel != null) {
            	String engineName = "NA";
            	String defaultEntityName = "NA";
            	String invoke = "NA";
            	String location = "NA";
            	if(UtilValidate.isNotEmpty(curServiceModel.engineName)) {engineName = curServiceModel.engineName;}
            	if(UtilValidate.isNotEmpty(curServiceModel.defaultEntityName)) {defaultEntityName = curServiceModel.defaultEntityName;}
            	if(UtilValidate.isNotEmpty(curServiceModel.invoke)) {invoke = curServiceModel.invoke;}
            	if(UtilValidate.isNotEmpty(curServiceModel.location)) {location = curServiceModel.location;}
            	
                boolean requireNewTransaction = curServiceModel.requireNewTransaction;

                curServiceMap.put("engineName",engineName);
                curServiceMap.put("defaultEntityName",defaultEntityName);
                curServiceMap.put("invoke",invoke);
                curServiceMap.put("location",location);
                curServiceMap.put("definitionLocation",curServiceModel.definitionLocation.replaceFirst("file:/" + System.getProperty("ofbiz.home") + "/", ""));
                curServiceMap.put("requireNewTransaction",requireNewTransaction);

                servicesList.add(curServiceMap);
                servicesFoundCount++;
            }
        }
        result.put("nfsList", servicesList);
        result.put("totalCount", servicesFoundCount);
        
        } catch (GenericServiceException e) {
			Debug.logError(e.getMessage(), module);
			return ServiceUtil.returnError(e.getMessage());
		}
        
        return result;
    }
    
    public static  Map<String,Object> getWvToolsService(DispatchContext ctx, Map<String, ? extends Object> context){
    	Map<String,Object> result = ServiceUtil.returnSuccess();
    	String selectedService = (String) context.get("sel_service_name");
    	if (UtilValidate.isEmpty(selectedService)) {
    		return result;
    	}
    		Map curServiceMap = new HashMap();
    	    curServiceMap.put("serviceName", selectedService);
            ModelService curServiceModel;
			try {
				curServiceModel = ctx.getModelService(selectedService);
			

    	    if (curServiceModel != null) {
    	        curServiceMap.put("description", curServiceModel.description) ;
    	        
    	        
    	        
    	        String engineName = "NA";
            	String defaultEntityName = "NA";
            	String invoke = "NA";
            	String location = "NA";
            	String export="否";
            	boolean exportBool=false;
            	List<ModelPermGroup> permissionGroups = new LinkedList<ModelPermGroup>();
            	Set<ModelServiceIface> implServices = new LinkedHashSet<ModelServiceIface>();
            	Set<ModelParam> overrideParameters = new LinkedHashSet<ModelParam>();
            	String useTrans="否";
            	
            	
            	if(UtilValidate.isNotEmpty(curServiceModel.engineName)) {engineName = curServiceModel.engineName;}
            	if(UtilValidate.isNotEmpty(curServiceModel.defaultEntityName)) {defaultEntityName = curServiceModel.defaultEntityName;}
            	if(UtilValidate.isNotEmpty(curServiceModel.invoke)) {invoke = curServiceModel.invoke;}
            	if(UtilValidate.isNotEmpty(curServiceModel.location)) {location = curServiceModel.location;}
            	if(curServiceModel.export) {export = "是";}
            	if(curServiceModel.export) {exportBool = true;}
            	if(UtilValidate.isNotEmpty(curServiceModel.permissionGroups)) {permissionGroups = curServiceModel.permissionGroups;}
            	if(UtilValidate.isNotEmpty(curServiceModel.implServices)) {implServices = curServiceModel.implServices;}
            	if(UtilValidate.isNotEmpty(curServiceModel.overrideParameters)) {overrideParameters = curServiceModel.overrideParameters;}
            	if(curServiceModel.useTransaction) {useTrans = "是";}
            	
                //boolean requireNewTransaction = curServiceModel.requireNewTransaction;
                int maxRetry = curServiceModel.maxRetry;
                

    	        //Test for ECA's
                /** TODO 20191118 需完善
    	        List ecaMapList = getEcaListForService(selectedService);
    	        if (UtilValidate.isNotEmpty(ecaMapList)) {
    	            result.put("ecaMapList", ecaMapList);
    	        }
    	        */
    	        //End Test for ECA's

    	        
    	        String requireNewTransaction="否";
    	        if(curServiceModel.requireNewTransaction) {requireNewTransaction = "是";}
    	        
    	        
    	        
    	        curServiceMap.put("engineName",engineName);
                curServiceMap.put("defaultEntityName",defaultEntityName);
                curServiceMap.put("invoke",invoke);
                curServiceMap.put("location",location);
                curServiceMap.put("definitionLocation",curServiceModel.definitionLocation.replaceFirst("file:/" + System.getProperty("ofbiz.home") + "/", ""));
                curServiceMap.put("requireNewTransaction",requireNewTransaction);
                curServiceMap.put("export",export);
                curServiceMap.put("exportBool",exportBool);
                

    	        if (UtilValidate.isNotEmpty(permissionGroups) && permissionGroups.size()>0) {
    	            List permList = new ArrayList(permissionGroups.size());
    	            
    	            for (ModelPermGroup curPerm : permissionGroups) { //This is a ModelPermGroup
    	            	 for (ModelPermission curPermObj : curPerm.permissions) { 
    	            
    	                    String permType="";
    	                    Map permObj = new HashMap();
    	                    permObj.put("action", curPermObj.action) ;
    	                    int old_permType = curPermObj.permissionType;
    	                    if (old_permType == 1) {
    	                        permType = "Simple Permission";
    	                    } else if (old_permType == 2) {
    	                        permType = "Entity Permission";
    	                    } else if (old_permType == 3) {
    	                        permType = "Role Member";
    	                    }
    	                    permObj.put("permType", permType) ;
    	                    permObj.put("nameOrRole", curPermObj.nameOrRole) ;
    	                   
    	                    permList.add(permObj);
    	                }
    	            }
    	            curServiceMap.put("permissionGroups", permList)  ;
    	        } else {
    	        	curServiceMap.put("permissionGroups", permissionGroups)  ;
    	           
    	        }

    	        curServiceMap.put("implServices",implServices);
    	        curServiceMap.put("useTrans",useTrans);
    	        curServiceMap.put("maxRetry",maxRetry);

    	        List allParamsList = new ArrayList(3);

    	        Set<String> inParams = curServiceModel.getInParamNames();
    	        List inParamsList = new ArrayList(inParams.size());
    	        for(String paramName:inParams) {
    	        //inParams.each { paramName ->
    	        	ModelParam curParam = curServiceModel.getParam(paramName);
    	            Map curInParam =   new HashMap();
    	            curInParam.put("entityName", curParam.entityName) ;
    	            curInParam.put("fieldName",curParam.fieldName) ;
    	            String internal="否"; if(curParam.internal) {internal="是"; }
    	            curInParam.put("internal", internal);
    	            curInParam.put("mode",curParam.mode) ;
    	            curInParam.put("name",curParam.name) ;
    	            curInParam.put("description",curParam.description) ;
    	            String optional="否"; if(curParam.optional) {internal="是"; }
    	            
    	            curInParam.put("optional",optional);
    	            curInParam.put("type",curParam.type) ;
    	            inParamsList.add(curInParam);
    	        }
    	        Map inParamMap =   new HashMap();
    	        inParamMap.put("title", "入参") ;
    	        inParamMap.put("paramList",inParamsList);
    	        allParamsList.add(inParamMap);

    	        Set<String> outParams = curServiceModel.getOutParamNames();
    	        List outParamsList = new ArrayList(outParams.size());
    	        for(String paramName:outParams) {
    	        //outParams.each { paramName ->
    	        	ModelParam  curParam = curServiceModel.getParam(paramName);
    	        	Map curOutParam =  new HashMap();
    	            curOutParam.put("entityName", curParam.entityName) ;
    	            curOutParam.put("fieldName",curParam.fieldName) ;
    	            
    	            String internal="否"; if(curParam.internal) {internal="是"; }
    	            curOutParam.put("internal", internal);
    	            curOutParam.put("mode",curParam.mode) ;
    	            curOutParam.put("name",curParam.name) ;
    	            curOutParam.put("description",curParam.description) ;
                    String optional="否"; if(curParam.optional) {internal="是"; }
                    curOutParam.put("optional",optional);
                    curOutParam.put("type",curParam.type) ;
    	            outParamsList.add(curOutParam);
    	        }
    	        Map outParamMap =   new HashMap();
    	        outParamMap.put("title", "出参") ;
    	        outParamMap.put("paramList",outParamsList);
    	        allParamsList.add(outParamMap);

    	        if (UtilValidate.isNotEmpty(overrideParameters)) {
    	            List ovrPrmList = new ArrayList(overrideParameters.size());
    	            for(ModelParam curParam:overrideParameters) {
    	           // overrideParameters.each { curParam ->
    	                Map curOvrPrm   = new HashMap();
        	        	curOvrPrm.put("entityName", curParam.entityName) ;
        	        	curOvrPrm.put("fieldName",curParam.fieldName) ;
        	            String internal="否"; if(curParam.internal) {internal="是"; }
        	            curOvrPrm.put("internal", internal);
        	            curOvrPrm.put("mode",curParam.mode) ;
        	            curOvrPrm.put("name",curParam.name) ;
        	            curOvrPrm.put("description",curParam.description) ;
                        String optional="否"; if(curParam.optional) {internal="是"; }
                        curOvrPrm.put("optional",optional);
                        curOvrPrm.put("type",curParam.type) ;
                        ovrPrmList.add(curOvrPrm);
    	            }
    	            Map ovrParamMap  = new HashMap();
    	            ovrParamMap.put("title", "Override parameters") ;
    	            ovrParamMap.put("paramList",ovrPrmList);
    	            allParamsList.add(ovrParamMap);
    	        }
    	        curServiceMap.put("allParamsList", allParamsList);
    	    }
    	    result.put("nfs", curServiceMap);
			} catch (GenericServiceException e) {
				Debug.logError(e.getMessage(), module);
				return ServiceUtil.returnError(e.getMessage());
			}
            return result;
    }
    /**
    private static List getEcaListForService(String selectedService) {
    	Map<String, List<ServiceEcaRule>> ecaMap = org.ofbiz.service.eca.ServiceEcaUtil.getServiceEventMap(selectedService);

        if (UtilValidate.isEmpty(ecaMap)) { return null;}

        //ecaMap is a HashMap so get keyset & iterate
        List ecaMapList =new ArrayList();

        
        for (Map.Entry<String, List<ServiceEcaRule>> ecaEntry: ecaMap.entrySet()) {
        	String ecaKey=ecaEntry.getKey();
        	List<ServiceEcaRule> ecaValue =ecaEntry.getValue();
        //ecaMap.each { ecaKey, ecaValue ->
        	for(ServiceEcaRule curRule:ecaValue ) {
           // ecaValue.each { curRule ->
                Map curRuleMap = new HashMap();
                curRuleMap.put("ruleKey", ecaKey);
                Class curRuleClass = curRule.getClass();
              //event name for rule
                Field eventName = curRuleClass.getDeclaredField("eventName");
                eventName.setAccessible(true);
                Object eventNameVal = eventName.get(curRule);
                if (eventNameVal!=null) {
                    curRuleMap.put("eventName", (String)eventNameVal);
                }
                eventName.setAccessible(false);
                //runOnError
                Field runOnError = curRuleClass.getDeclaredField("runOnError");
                runOnError.setAccessible(true);
                Object runOnErrorVal = runOnError.get(curRule);
                if (runOnErrorVal!=null) {
                    curRuleMap.put("runOnError", (String)runOnErrorVal);
                }
                runOnError.setAccessible(false);
                
                
                
                
                //runOnFailure
                Field runOnFailure = curRuleClass.getDeclaredField("runOnFailure");
                runOnFailure.setAccessible(true);
                Object runOnFailureVal = runOnFailure.get(curRule);
                if (runOnFailureVal!=null) {
                    curRuleMap.put("runOnFailure", (String)runOnFailureVal);
                }
                runOnFailure.setAccessible(false);

                //extract actions
                Field actions = curRuleClass.getDeclaredField("actionsAndSets");
                actions.setAccessible(true);
                List<Object>  actionsVal = (List<Object>) actions.get(curRule);
                if (actionsVal!=null) {
                    List actionsList = new ArrayList();
                    List setsList = new ArrayList();
                    for(Object curAction:actionsVal) {
                    //actionsVal.each { curAction ->
                        Class actionClass = curAction.getClass();
                        if (org.ofbiz.service.eca.ServiceEcaAction.equals(actionClass)) {
                            Map actionMap = new HashMap();

                            //eventName
                             eventName = actionClass.getDeclaredField("eventName");
                            eventName.setAccessible(true);
                            eventNameVal = eventName.get(curAction);
                            if (eventNameVal!=null) {
                                actionMap.put("eventName", (String)eventNameVal);
                            }
                            eventName.setAccessible(false);

                            //ignoreError
                            Field ignoreError = actionClass.getDeclaredField("ignoreError");
                            ignoreError.setAccessible(true);
                            Object ignoreErrorVal = ignoreError.get(curAction);
                            if (ignoreErrorVal!=null) {
                                actionMap.put("ignoreError", (String)ignoreErrorVal);
                            }
                            ignoreError.setAccessible(false);

                            //ignoreFailure
                            Field ignoreFailure = actionClass.getDeclaredField("ignoreFailure");
                            ignoreFailure.setAccessible(true);
                            ignoreFailureVal = ignoreFailure.get(curAction);
                            if (ignoreFailureVal) {
                                actionMap.put("ignoreFailure", (String)ignoreFailureVal);
                            }
                            ignoreFailure.setAccessible(false);

                            //persist
                            persist = actionClass.getDeclaredField("persist");
                            persist.setAccessible(true);
                            persistVal = persist.get(curAction);
                            if (persistVal) {
                                actionMap.put("persist", (String)persistVal);
                            }
                            persist.setAccessible(false);

                            //resultMapName
                            Field resultMapName = actionClass.getDeclaredField("resultMapName");
                            resultMapName.setAccessible(true);
                            resultMapNameVal = resultMapName.get(curAction);
                            if (resultMapNameVal) {
                                actionMap.put("resultMapName", (String)resultMapNameVal);
                            }
                            resultMapName.setAccessible(false);

                            //resultToContext
                            resultToContext = actionClass.getDeclaredField("resultToContext");
                            resultToContext.setAccessible(true);
                            resultToContextVal = resultToContext.get(curAction);
                            if (resultToContextVal) {
                                actionMap.put("resultToContext", (String)resultToContextVal);
                            }
                            resultToContext.setAccessible(false);

                            //resultToResult
                            resultToResult = actionClass.getDeclaredField("resultToResult");
                            resultToResult.setAccessible(true);
                            resultToResultVal = resultToResult.get(curAction);
                            if (resultToResultVal) {
                                actionMap.put("resultToResult", (String)resultToResultVal);
                            }
                            resultToResult.setAccessible(false);

                            //serviceMode
                            serviceMode = actionClass.getDeclaredField("serviceMode");
                            serviceMode.setAccessible(true);
                            serviceModeVal = serviceMode.get(curAction);
                            if (serviceModeVal) {
                                actionMap.put("serviceMode", (String)serviceModeVal);
                            }
                            serviceMode.setAccessible(false);

                            //serviceName
                            serviceName = actionClass.getDeclaredField("serviceName");
                            serviceName.setAccessible(true);
                            serviceNameVal = serviceName.get(curAction);
                            if (serviceNameVal) {
                                actionMap.put("serviceName", (String)serviceNameVal);
                            }
                            serviceName.setAccessible(false);

                            actionsList.add(actionMap);

                        } else {  // FIXME : we should also show field-names and values for set operation
                            Map setMap = new HashMap();

                            // fieldName
                            Field fieldName = actionClass.getDeclaredField("fieldName");
                            fieldName.setAccessible(true);
                            fieldNameVal = fieldName.get(curAction);
                            if (fieldNameVal) {
                                setMap.put("fieldName", (String)fieldNameVal);
                            }
                            fieldName.setAccessible(false);

                            // envName
                            envName = actionClass.getDeclaredField("envName");
                            envName.setAccessible(true);
                            envNameVal = envName.get(curAction);
                            if (envNameVal) {
                                setMap.put("envName", (String)envNameVal);
                            }
                            envName.setAccessible(false);

                            // value
                            value = actionClass.getDeclaredField("value");
                            value.setAccessible(true);
                            valueVal = value.get(curAction);
                            if (valueVal) {
                                setMap.put("value", (String)valueVal);
                            }
                            value.setAccessible(false);

                            // format
                            format = actionClass.getDeclaredField("format");
                            format.setAccessible(true);
                            formatVal = format.get(curAction);
                            if (formatVal) {
                                setMap.put("format", (String)formatVal);
                            }
                            format.setAccessible(false);

                            setsList.add(setMap);
                        }
                    }

                    curRuleMap.actions = actionsList;
                    curRuleMap.sets= setsList;
                }
                actions.setAccessible(true);

                //extract conditions
                Field conditions = curRuleClass.getDeclaredField("conditions");
                conditions.setAccessible(true);
                List<Object> conditionsVal = (List<Object>) conditions.get(curRule);
                if (conditionsVal) {
                    curRuleMap.put("conditions",(String)runOnFailureVal);
                    condList = new ArrayList(conditionsVal.size());
                    for(Object condVal:conditionsVal)
                   // conditionsVal.each { condVal ->
                        condValClass = condVal.getClass();
                        Map condMap =  new HashMap();

                        //compareType
                        compareType = condValClass.getDeclaredField("compareType");
                        compareType.setAccessible(true);
                        compareTypeVal = compareType.get(condVal);
                        if (compareTypeVal) {
                            condMap.put("compareType",(String)compareTypeVal);
                        }
                        compareType.setAccessible(false);

                        //conditionService
                        conditionService = condValClass.getDeclaredField("conditionService");
                        conditionService.setAccessible(true);
                        conditionServiceVal = conditionService.get(condVal);
                        if (conditionServiceVal) {
                            condMap.put("conditionService",(String)conditionServiceVal);
                        }
                        conditionService.setAccessible(false);

                        //format
                        format = condValClass.getDeclaredField("format");
                        format.setAccessible(true);
                        formatVal = format.get(condVal);
                        if (formatVal) {
                            condMap.put("format",(String)formatVal);
                        }
                        format.setAccessible(false);

                        //isConstant
                        isConstant = condValClass.getDeclaredField("isConstant");
                        isConstant.setAccessible(true);
                        isConstantVal = isConstant.get(condVal);
                        if (isConstantVal) {
                            condMap.put("isConstant",(String)isConstantVal);
                        }
                        isConstant.setAccessible(false);

                        //isService
                        isService = condValClass.getDeclaredField("isService");
                        isService.setAccessible(true);
                        isServiceVal = isService.get(condVal);
                        if (isServiceVal) {
                            condMap.put("isService",(String)isServiceVal);
                        }
                        isService.setAccessible(false);

                        //lhsMapName
                        lhsMapName = condValClass.getDeclaredField("lhsMapName");
                        lhsMapName.setAccessible(true);
                        lhsMapNameVal = lhsMapName.get(condVal);
                        if (lhsMapNameVal) {
                        	condMap.put("lhsMapName",(String)lhsMapNameVal);
                        }
                        lhsMapName.setAccessible(false);

                        //lhsValueName
                        lhsValueName = condValClass.getDeclaredField("lhsValueName");
                        lhsValueName.setAccessible(true);
                        lhsValueNameVal = lhsValueName.get(condVal);
                        if (lhsValueNameVal) {
                            condMap.put("lhsValueName",(String)lhsValueNameVal);
                        }
                        lhsValueName.setAccessible(false);

                        //operator
                        operator = condValClass.getDeclaredField("operator");
                        operator.setAccessible(true);
                        operatorVal = operator.get(condVal);
                        if (operatorVal) {
                            condMap.put("operator",(String)operatorVal);
                        }
                        operator.setAccessible(false);

                        //rhsMapName
                        rhsMapName = condValClass.getDeclaredField("rhsMapName");
                        rhsMapName.setAccessible(true);
                        rhsMapNameVal = rhsMapName.get(condVal);
                        if (rhsMapNameVal) {
                            condMap.put("rhsMapName",(String)rhsMapNameVal);
                        }
                        rhsMapName.setAccessible(false);

                        //rhsValueName
                        Field rhsValueName = condValClass.getDeclaredField("rhsValueName");
                        rhsValueName.setAccessible(true);
                        rhsValueNameVal = rhsValueName.get(condVal);
                        if (rhsValueNameVal) {
                            condMap.put("rhsValueName",(String)rhsValueNameVal);
                        }
                        rhsValueName.setAccessible(false);

                        condList.add(condMap);
                    }
                    curRuleMap.conditions = condList;
                }
                conditions.setAccessible(false);

                ecaMapList.add(curRuleMap);
            }
       // }
        return ecaMapList;
    }
*/
    public static  Map<String,Object> getSyncServiceParameters(DispatchContext ctx, Map<String, ? extends Object> context){
    	Map<String,Object> result = ServiceUtil.returnSuccess();
//    	savedSyncResult = null;
//    	if (session.getAttribute("_SAVED_SYNC_RESULT_") != null) {
//    	    savedSyncResult = session.getAttribute("_SAVED_SYNC_RESULT_");
//    	}
    	 LocalDispatcher dispatcher = ctx.getDispatcher();
    	 String serviceName = (String) context.get("sel_service_name");
    	 
    	 if (UtilValidate.isEmpty(serviceName)) {
     		return result;
     	}

//    	scheduleOptions = [];
//    	serviceParameters = [];
//    	e = request.getParameterNames();
//    	while (e.hasMoreElements()) {
//    	    paramName = e.nextElement();
//    	    paramValue = parameters[paramName];
//    	    scheduleOptions.add([name : paramName, value : paramValue]);
//    	}

    	//context.scheduleOptions = scheduleOptions;
    	List serviceParameters = new ArrayList();
    	    
    	    try {
    	    	String POOL_NAME = ServiceConfigUtil.getServiceEngine().getThreadPool().getSendToPool();
    	    	ModelService modelService = ctx.getModelService(serviceName);
    	    	if (modelService != null) {
        	        Set<String> inParams = modelService.getInParamNames();
        	        for(String paramName:inParams) {
        	       
        	        	ModelParam curParam = modelService.getParam(paramName);
        	            if (curParam.internal) {
        	                continue;
        	            }
        	            Map serviceParam =   new HashMap();
        	            serviceParam.put("name",curParam.name) ;
        	            serviceParam.put("type",curParam.type) ;
        	            String optional="否"; if(curParam.optional) {optional="是"; }
        	            serviceParam.put("optional",optional);
        	            serviceParam.put("defaultValue", curParam.getDefaultValue()) ;
        	            //curInParam.put("value",参数) ;
        	            serviceParameters.add(serviceParam);
        	        }
        	        
        	    }
    	    	result.put("nfsList", serviceParameters);
    	    } catch (Exception e) {
    	    	 Debug.logError(e.getMessage(), module);
     			return ServiceUtil.returnError(e.getMessage());
    	    }
    	    
    	return result;
    }
    
    
    /**
     * Schedule a service for a specific time or recurrence
     *  Request Parameters which are used for this service:
     *
     *  SERVICE_NAME      - Name of the service to invoke
     *  SERVICE_TIME      - First time the service will occur
     *  SERVICE_FREQUENCY - The type of recurrence (SECONDLY,MINUTELY,DAILY,etc)
     *  SERVICE_INTERVAL  - The interval of the frequency (every 5 minutes, etc)
     *
     * @param request HttpServletRequest
     * @param response HttpServletResponse
     * @return Response code string
     */
    public static  Map<String,Object> scheduleServiceSync(DispatchContext ctx, Map<String, ? extends Object> context){
    	Map<String,Object> result = ServiceUtil.returnSuccess();
      
//      //  public static String scheduleService(HttpServletRequest request, HttpServletResponse response) {
//            Security security = (Security) request.getAttribute("security");
//            GenericValue userLogin = (GenericValue) request.getSession().getAttribute("userLogin");
//           
//            //Delegator delegator = (Delegator) request.getAttribute("delegator");
    	 LocalDispatcher dispatcher = ctx.getDispatcher();
            Locale locale = (Locale) context.get("locale");
            TimeZone timeZone = (TimeZone) context.get("timeZone");
            GenericValue userLogin = (GenericValue) context.get("userLogin");
//            TimeZone timeZone = UtilHttp.getTimeZone(request);
//
//            Map<String, Object> params = UtilHttp.getParameterMap(request);
            // get the schedule parameters
            String jobName = (String) context.get("JOB_NAME");
            String serviceName = (String) context.get("sel_service_name");
            String poolName = (String) context.get("POOL_NAME");
            String serviceTime = (String) context.get("SERVICE_TIME");
            String serviceEndTime = (String) context.get("SERVICE_END_TIME");
            String serviceFreq = (String) context.get("SERVICE_FREQUENCY");
            String serviceIntr = (String) context.get("SERVICE_INTERVAL");
            String serviceCnt = (String) context.get("SERVICE_COUNT");
            String retryCnt = (String) context.get("SERVICE_MAXRETRY");
            
            String _RUN_SYNC_ = (String) context.get("_RUN_SYNC_");
            
            
           

            // the frequency map
            Map<String, Integer> freqMap = new HashMap<String, Integer>();

            freqMap.put("SECONDLY", Integer.valueOf(1));
            freqMap.put("MINUTELY", Integer.valueOf(2));
            freqMap.put("HOURLY", Integer.valueOf(3));
            freqMap.put("DAILY", Integer.valueOf(4));
            freqMap.put("WEEKLY", Integer.valueOf(5));
            freqMap.put("MONTHLY", Integer.valueOf(6));
            freqMap.put("YEARLY", Integer.valueOf(7));

            // some defaults
            long startTime = (new Date()).getTime();
            long endTime = 0;
            int maxRetry = -1;
            int count = 1;
            int interval = 1;
            int frequency = RecurrenceRule.DAILY;

            StringBuilder errorBuf = new StringBuilder();

            // make sure we passed a service
            if (serviceName == null) {
                String errMsg = UtilProperties.getMessage(CoreEvents.err_resource, "coreEvents.must_specify_service", locale);
                Debug.logError(errMsg, module);
    			return ServiceUtil.returnError(errMsg);
            }

            // lookup the service definition to see if this service is externally available, if not require the SERVICE_INVOKE_ANY permission
            ModelService modelService = null;
            try {
                modelService = dispatcher.getDispatchContext().getModelService(serviceName);
            } catch (GenericServiceException e) {
                Debug.logError(e, "Error looking up ModelService for serviceName [" + serviceName + "]", module);
                String errMsg = UtilProperties.getMessage(CoreEvents.err_resource, "coreEvents.error_modelservice_for_srv_name", locale);
                //request.setAttribute("_ERROR_MESSAGE_", errMsg + " [" + serviceName + "]: " + e.toString());
                //return "error";
                Debug.logError(errMsg, module);
    			return ServiceUtil.returnError(errMsg);
            }
            if (modelService == null) {
                String errMsg = UtilProperties.getMessage(CoreEvents.err_resource, "coreEvents.service_name_not_find", locale);
                //request.setAttribute("_ERROR_MESSAGE_", errMsg + " [" + serviceName + "]");
                //return "error";
                Debug.logError(errMsg, module);
    			return ServiceUtil.returnError(errMsg);
            }

            // make the context valid; using the makeValid method from ModelService
            Map<String, Object> serviceContext = new HashMap<String, Object>();
//            Iterator<String> ci = modelService.getInParamNames().iterator();
//            while (ci.hasNext()) {
//                String name = ci.next();
//
//                // don't include userLogin, that's taken care of below
//                if ("userLogin".equals(name)) continue;
//                // don't include locale, that is also taken care of below
//                if ("locale".equals(name)) continue;
//
//                Object value = request.getParameter(name);
//
//                // if the parameter wasn't passed and no other value found, don't pass on the null
//                if (value == null) {
//                    value = request.getAttribute(name);
//                }
//                if (value == null) {
//                    value = request.getSession().getAttribute(name);
//                }
//                if (value == null) {
//                    // still null, give up for this one
//                    continue;
//                }
//
//                if (value instanceof String && ((String) value).length() == 0) {
//                    // interpreting empty fields as null values for each in back end handling...
//                    value = null;
//                }
//
//                // set even if null so that values will get nulled in the db later on
//                serviceContext.put(name, value);
//            }
            serviceContext = modelService.makeValid(context, ModelService.IN_PARAM, true, null, timeZone, locale);

            if (userLogin != null) {
                serviceContext.put("userLogin", userLogin);
            }

            if (locale != null) {
                serviceContext.put("locale", locale);
            }

//            if (!modelService.export && !security.hasPermission("SERVICE_INVOKE_ANY", request.getSession())) {
//                String errMsg = UtilProperties.getMessage(CoreEvents.err_resource, "coreEvents.not_authorized_to_call", locale);
//                request.setAttribute("_ERROR_MESSAGE_", errMsg);
//                return "error";
//            }

            // some conversions
            if (UtilValidate.isNotEmpty(serviceTime)) {
                try {
                    Timestamp ts1 = Timestamp.valueOf(serviceTime);
                    startTime = ts1.getTime();
                } catch (IllegalArgumentException e) {
                    try {
                        startTime = Long.parseLong(serviceTime);
                    } catch (NumberFormatException nfe) {
                        String errMsg = UtilProperties.getMessage(CoreEvents.err_resource, "coreEvents.invalid_format_time", locale);
                        errorBuf.append(errMsg);
                    }
                }
                if (startTime < (new Date()).getTime()) {
                    String errMsg = UtilProperties.getMessage(CoreEvents.err_resource, "coreEvents.service_time_already_passed", locale);
                    errorBuf.append(errMsg);
                }
            }
            if (UtilValidate.isNotEmpty(serviceEndTime)) {
                try {
                    Timestamp ts1 = Timestamp.valueOf(serviceEndTime);
                    endTime = ts1.getTime();
                } catch (IllegalArgumentException e) {
                    try {
                        endTime = Long.parseLong(serviceTime);
                    } catch (NumberFormatException nfe) {
                        String errMsg = UtilProperties.getMessage(CoreEvents.err_resource, "coreEvents.invalid_format_time", locale);
                        errorBuf.append(errMsg);
                    }
                }
                if (endTime < (new Date()).getTime()) {
                    String errMsg = UtilProperties.getMessage(CoreEvents.err_resource, "coreEvents.service_time_already_passed", locale);
                    errorBuf.append(errMsg);
                }
            }
            if (UtilValidate.isNotEmpty(serviceIntr)) {
                try {
                    interval = Integer.parseInt(serviceIntr);
                } catch (NumberFormatException nfe) {
                    String errMsg = UtilProperties.getMessage(CoreEvents.err_resource, "coreEvents.invalid_format_interval", locale);
                    errorBuf.append(errMsg);
                }
            }
            if (UtilValidate.isNotEmpty(serviceCnt)) {
                try {
                    count = Integer.parseInt(serviceCnt);
                } catch (NumberFormatException nfe) {
                    String errMsg = UtilProperties.getMessage(CoreEvents.err_resource, "coreEvents.invalid_format_count", locale);
                    errorBuf.append(errMsg);
                }
            }
            if (UtilValidate.isNotEmpty(serviceFreq)) {
                int parsedValue = 0;

                try {
                    parsedValue = Integer.parseInt(serviceFreq);
                    if (parsedValue > 0 && parsedValue < 8)
                        frequency = parsedValue;
                } catch (NumberFormatException nfe) {
                    parsedValue = 0;
                }
                if (parsedValue == 0) {
                    if (!freqMap.containsKey(serviceFreq.toUpperCase())) {
                        String errMsg = UtilProperties.getMessage(CoreEvents.err_resource, "coreEvents.invalid_format_frequency", locale);
                        errorBuf.append(errMsg);
                    } else {
                        frequency = freqMap.get(serviceFreq.toUpperCase()).intValue();
                    }
                }
            }
            if (UtilValidate.isNotEmpty(retryCnt)) {
                int parsedValue = -2;

                try {
                    parsedValue = Integer.parseInt(retryCnt);
                } catch (NumberFormatException e) {
                    parsedValue = -2;
                }
                if (parsedValue > -2) {
                    maxRetry = parsedValue;
                } else {
                    maxRetry = modelService.maxRetry;
                }
            } else {
                maxRetry = modelService.maxRetry;
            }

            // return the errors
            if (errorBuf.length() > 0) {
                //request.setAttribute("_ERROR_MESSAGE_", errorBuf.toString());
                //return "error";
                Debug.logError(errorBuf.toString(), module);
    			return ServiceUtil.returnError(errorBuf.toString());
            }

            Map<String, Object> syncServiceResult = null;
            // schedule service
            try {
            	
            	
                if (null!=context.get("_RUN_SYNC_") && _RUN_SYNC_.equals("Y")) {
                    syncServiceResult = dispatcher.runSync(serviceName, serviceContext);
                } else {
                    dispatcher.schedule(jobName, poolName, serviceName, serviceContext, startTime, frequency, interval, count, endTime, maxRetry);
                }
            } catch (GenericServiceException e) {
                String errMsg = UtilProperties.getMessage(CoreEvents.err_resource, "coreEvents.service_dispatcher_exception", locale);
                //request.setAttribute("_ERROR_MESSAGE_", errMsg + e.getMessage());
                //return "error";
                Debug.logError(errMsg, module);
    			return ServiceUtil.returnError(errMsg);
            }

            String errMsg = UtilProperties.getMessage(CoreEvents.err_resource, "coreEvents.service_scheduled", locale);
            result.put("_EVENT_MESSAGE_", errMsg);
            if (null!=syncServiceResult) {
            	result.put("_RUN_SYNC_RESULT_", syncServiceResult);
            	result.put("nfs", syncServiceResult);
//                return "sync_success";
                Debug.logError(errMsg, module);
    			return result;
            }
            return result;
        }
   
    
    
    
}
